define(function (require, exports, module) {
    'use strict';
    var $ = require('jquery'),
        plupload = require('plupload'),
        Qiniu = require('qiniu'),
        notify = require('js/utils/notify');

    var FileProgress = function (file, targetID) {
        this.fileProgressID = file.id;
        this.file = file;

        this.opacity = 100;
        this.height = 0;
        this.fileProgressWrapper = $('#' + this.fileProgressID);
        if (!this.fileProgressWrapper.length) {
            // <div class="progress">
            //   <div class="progress-bar progress-bar-info" role="progressbar" aria-valuenow="20" aria-valuemin="0" aria-valuemax="100" style="width: 20%">
            //     <span class="sr-only">20% Complete</span>
            //   </div>
            // </div>

            this.fileProgressWrapper = $('<tr></tr>');
            var Wrappeer = this.fileProgressWrapper;
            Wrappeer.attr('id', this.fileProgressID).addClass('progressContainer');

            var progressText = $("<td/>");
            progressText.addClass('progressName');


            var fileSize = plupload.formatSize(file.size).toUpperCase();
            var progressSize = $("<td/>");
            progressSize.addClass("progressFileSize").text(fileSize);

            var progressBarTd = $("<td/>");
            var progressBarBox = $("<div/>");
            progressBarBox.addClass('info');
            var progressBarWrapper = $("<div/>");
            progressBarWrapper.addClass("progress progress-striped");

            var progressBar = $("<div/>");
            progressBar.addClass("progress-bar progress-bar-info")
                .attr('role', 'progressbar')
                .attr('aria-valuemax', 100)
                .attr('aria-valuenow', 0)
                .attr('aria-valuein', 0)
                .width('0%');

            var progressBarPercent = $('<span class=sr-only />');
            progressBarPercent.text(fileSize);

            var progressCancel = $('<a href=javascript:; />');
            progressCancel.show().addClass('progressCancel').text('×');

            progressBar.append(progressBarPercent);
            progressBarWrapper.append(progressBar);
            progressBarBox.append(progressBarWrapper);
            progressBarBox.append(progressCancel);

            var progressBarStatus = $('<div class="status text-center"/>');
            progressBarBox.append(progressBarStatus);
            progressBarTd.append(progressBarBox);

            Wrappeer.append(progressText);
            Wrappeer.append(progressSize);
            Wrappeer.append(progressBarTd);

            $('#' + targetID).append(Wrappeer);
        } else {
            this.reset();
        }

        this.height = this.fileProgressWrapper.offset().top;
        this.setTimer(null);
    }

    FileProgress.prototype.setTimer = function (timer) {
        this.fileProgressWrapper.FP_TIMER = timer;
    };

    FileProgress.prototype.getTimer = function (timer) {
        return this.fileProgressWrapper.FP_TIMER || null;
    };

    FileProgress.prototype.reset = function () {
        this.fileProgressWrapper.attr('class', "progressContainer");
        this.fileProgressWrapper.find('td .progress .progress-bar-info').attr('aria-valuenow', 0).width('0%').find('span').text('');
        this.appear();
    };

    FileProgress.prototype.setChunkProgess = function (chunk_size) {
        var chunk_amount = Math.ceil(this.file.size / chunk_size);
        if (chunk_amount === 1) {
            return false;
        }

        var viewProgess = $('<button class="btn btn-default">查看分块上传进度</button>');

        var progressBarChunkTr = $('<tr class="chunk-status-tr"><td colspan=3></td></tr>');
        var progressBarChunk = $('<div/>');
        for (var i = 1; i <= chunk_amount; i++) {
            var col = $('<div class="col-md-2"/>');
            var progressBarWrapper = $('<div class="progress progress-striped"></div');

            var progressBar = $("<div/>");
            progressBar.addClass("progress-bar progress-bar-info text-left")
                .attr('role', 'progressbar')
                .attr('aria-valuemax', 100)
                .attr('aria-valuenow', 0)
                .attr('aria-valuein', 0)
                .width('0%')
                .attr('id', this.file.id + '_' + i)
                .text('');

            var progressBarStatus = $('<span/>');
            progressBarStatus.addClass('chunk-status').text();

            progressBarWrapper.append(progressBar);
            progressBarWrapper.append(progressBarStatus);

            col.append(progressBarWrapper);
            progressBarChunk.append(col);
        }

        if (!this.fileProgressWrapper.find('td:eq(2) .btn-default').length) {
            this.fileProgressWrapper.find('td>div').append(viewProgess);
        }
        progressBarChunkTr.hide().find('td').append(progressBarChunk);
        progressBarChunkTr.insertAfter(this.fileProgressWrapper);

    };

    FileProgress.prototype.setProgress = function (percentage, speed, chunk_size) {
        this.fileProgressWrapper.attr('class', "progressContainer green");

        var file = this.file;
        var uploaded = file.loaded;

        var size = plupload.formatSize(uploaded).toUpperCase();
        var formatSpeed = plupload.formatSize(speed).toUpperCase();
        var progressbar = this.fileProgressWrapper.find('td .progress').find('.progress-bar-info');
        if (this.fileProgressWrapper.find('.status').text() === '取消上传') {
            return;
        }
        this.fileProgressWrapper.find('.status').text("已上传: " + size + " 上传速度： " + formatSpeed + "/s");
        percentage = parseInt(percentage, 10);
        if (file.status !== plupload.DONE && percentage === 100) {
            percentage = 99;
        }

        progressbar.attr('aria-valuenow', percentage).css('width', percentage + '%');

        if (chunk_size) {
            var chunk_amount = Math.ceil(file.size / chunk_size);
            if (chunk_amount === 1) {
                return false;
            }
            var current_uploading_chunk = Math.ceil(uploaded / chunk_size);
            var pre_chunk, text;

            for (var index = 0; index < current_uploading_chunk; index++) {
                pre_chunk = $('#' + file.id + "_" + index);
                pre_chunk.width('100%').removeClass().addClass('alert-success').attr('aria-valuenow', 100);
                text = "块" + index + "上传进度100%";
                pre_chunk.next().html(text);
            }

            var currentProgessBar = $('#' + file.id + "_" + current_uploading_chunk);
            var current_chunk_percent;
            if (current_uploading_chunk < chunk_amount) {
                if (uploaded % chunk_size) {
                    current_chunk_percent = ((uploaded % chunk_size) / chunk_size * 100).toFixed(2);
                } else {
                    current_chunk_percent = 100;
                    currentProgessBar.removeClass().addClass('alert-success');
                }
            } else {
                var last_chunk_size = file.size - chunk_size * (chunk_amount - 1);
                var left_file_size = file.size - uploaded;
                if (left_file_size % last_chunk_size) {
                    current_chunk_percent = ((uploaded % chunk_size) / last_chunk_size * 100).toFixed(2);
                } else {
                    current_chunk_percent = 100;
                    currentProgessBar.removeClass().addClass('alert-success');
                }
            }
            currentProgessBar.width(current_chunk_percent + '%');
            currentProgessBar.attr('aria-valuenow', current_chunk_percent);
            text = "块" + current_uploading_chunk + "上传进度" + current_chunk_percent + '%';
            currentProgessBar.next().html(text);
        }

        this.appear();
    };

    FileProgress.prototype.setComplete = function (up, info) {
        var td = this.fileProgressWrapper.find('td:eq(2)'),
            tdProgress = td.find('.progress');

        var res = $.parseJSON(info);
        var url, str;
        if (res.url) {
            url = res.url;
            str = "<div><a href=" + res.url + " target='_blank' >点击查看原图</a></div>";
        } else {
            var domain = up.getOption('domain');
            url = domain + encodeURI(res.key);
            var link = domain + res.key;
            str = "<div><a href=" + url + " target='_blank' >点击查看原图</a></div>";
        }

        tdProgress.html(str).removeClass().next().next('.status').hide();
        td.find('.progressCancel').hide();

        var progressNameTd = this.fileProgressWrapper.find('.progressName');
        var imageView = '?imageView2/1/w/100/h/100';

        var isImage = function (url) {
            var res, suffix = "";
            var imageSuffixes = ["png", "jpg", "jpeg", "gif", "bmp"];
            var suffixMatch = /\.([a-zA-Z0-9]+)(\?|\@|$)/;

            if (!url || !suffixMatch.test(url)) {
                return false;
            }
            res = suffixMatch.exec(url);
            suffix = res[1].toLowerCase();
            for (var i = 0, l = imageSuffixes.length; i < l; i++) {
                if (suffix === imageSuffixes[i]) {
                    return true;
                }
            }
            return false;
        };

        var isImg = isImage(url);

        var Wrapper = $('<div class="Wrapper"/>');
        var imgWrapper = $('<div class="imgWrapper col-md-3"/>');
        var linkWrapper = $('<a class="linkWrapper" target="_blank"/>');
        var showImg = $('<img src="lib/plugins/qiniu/loading.gif"/>');

        progressNameTd.append(Wrapper);

        if (!isImg) {
            showImg.attr('src', 'default.png');
            Wrapper.addClass('default');

            imgWrapper.append(showImg);
            Wrapper.append(imgWrapper);
        } else {
            linkWrapper.append(showImg);
            imgWrapper.append(linkWrapper);
            Wrapper.append(imgWrapper);

            var img = new Image();
            if (!/imageView/.test(url)) {
                url += imageView;
            }
            $(img).attr('src', url);

            var height_space = 340;
            $(img).on('load', function () {
                showImg.attr('src', url);

                function initImg(url, key, height) {
                    $('#myModal-img').modal();
                    var modalBody = $('#myModal-img').find('.modal-body');
                    if (height <= 300) {
                        $('#myModal-img').find('.text-warning').show();
                    }
                    var newImg = new Image();
                    modalBody.find('img').attr('src', 'loading.gif');
                    newImg.onload = function () {
                        modalBody.find('img').attr('src', url).data('key', key).data('h', height);
                        modalBody.find('.modal-body-wrapper').find('a').attr('href', url);
                    };
                    newImg.src = url;
                }
            }).on('error', function () {
                showImg.attr('src', 'default.png');
                Wrapper.addClass('default');
            });
        }
    };
    FileProgress.prototype.setError = function () {
        this.fileProgressWrapper.find('td:eq(2)').attr('class', 'text-warning');
        this.fileProgressWrapper.find('td:eq(2) .progress').css('width', 0).hide();
        this.fileProgressWrapper.find('button').hide();
        this.fileProgressWrapper.next('.chunk-status-tr').hide();
    };

    FileProgress.prototype.setCancelled = function (manual) {
        var progressContainer = 'progressContainer';
        if (!manual) {
            progressContainer += ' red';
        }
        this.fileProgressWrapper.attr('class', progressContainer);
        this.fileProgressWrapper.find('td .progress').remove();
        this.fileProgressWrapper.find('td:eq(2) .btn-default').hide();
        this.fileProgressWrapper.find('td:eq(2) .progressCancel').hide();
    };

    FileProgress.prototype.setStatus = function (status, isUploading) {
        if (!isUploading) {
            this.fileProgressWrapper.find('.status').text(status).attr('class', 'status text-left');
        }
    };

    // 绑定取消上传事件
    FileProgress.prototype.bindUploadCancel = function (up) {
        var self = this;
        if (up) {
            self.fileProgressWrapper.find('td:eq(2) .progressCancel').on('click', function () {
                self.setCancelled(false);
                self.setStatus("取消上传");
                self.fileProgressWrapper.find('.status').css('left', '0');
                up.removeFile(self.file);
            });
        }

    };

    FileProgress.prototype.appear = function () {
        if (this.getTimer() !== null) {
            clearTimeout(this.getTimer());
            this.setTimer(null);
        }

        if (this.fileProgressWrapper[0].filters) {
            try {
                this.fileProgressWrapper[0].filters.item("DXImageTransform.Microsoft.Alpha").opacity = 100;
            } catch (e) {
                // If it is not set initially, the browser will throw an error.  This will set it if it is not set yet.
                this.fileProgressWrapper.css('filter', "progid:DXImageTransform.Microsoft.Alpha(opacity=100)");
            }
        } else {
            this.fileProgressWrapper.css('opacity', 1);
        }

        this.fileProgressWrapper.css('height', '');

        this.height = this.fileProgressWrapper.offset().top;
        this.opacity = 100;
        this.fileProgressWrapper.show();

    };
    var getFileExtension = function (filename) {
        var tempArr = filename.split(".");
        var ext;
        if (tempArr.length === 1 || (tempArr[0] === "" && tempArr.length === 2)) {
            ext = "";
        } else {
            ext = tempArr.pop().toLowerCase(); //get the extension and make it lower-case
        }
        return ext;
    };

    var _getUploaderParams = function (btnId, forAvatar) {
        var uptoken_url = '/admin/uptoken/',
            domain = window.QINIU_DOMAIN || 'http://7xod1l.com1.z0.glb.clouddn.com/';
        if (forAvatar) {
            uptoken_url = window.UPTOKEN_URL || uptoken_url;
            domain = window.AVATAR_DOMAIN || domain;
        }
        var params = {
            runtimes: 'html5,flash,html4',
            browse_button: btnId,
            container: 'container',
            drop_element: 'container',
            max_file_size: '10mb',
            flash_swf_url: 'lib/plugins/plupload/js/Moxie.swf', //引入flash,相对路径
            max_retries: 3, //上传失败最大重试次数
            dragdrop: true,
            chunk_size: '4mb',
            domain: domain,
            get_new_uptoken: false,
            uptoken_url: uptoken_url,
            filters: {
                mime_types: [ //只允许上传图片文件
                    {
                        title: "图片文件",
                        extensions: "jpg,gif,png,bmp,jpeg"
                    },
                ],
                prevent_duplicates: true //不允许队列中存在重复文件
            },
            auto_start: true
        };
        if (!forAvatar) {
            params.unique_names = true;
        } else {
            params.unique_names = false;
            params.save_key = false;
            params.init = {};
            params.init.Key = function (up, file) {
                var key = "avatars/",
                    ext = getFileExtension(file.name),
                    name = ext ? file.id + '.' + ext : file.id;
                // do something with key heregetElementById
                return key + name;
            };
        }
        return params;
    };

    var setProcess = function (values, barId) {
        if (values.max != null) $('#' + barId).attr('aria-valuemax', values.max);
        if (values.now != null) $('#' + barId).css('width', values.now + '%').attr('aria-valuenow', values.now);
    };
    var getProcess = function (barId) {
        return {
            max: $('#' + barId).attr('aria-valuenow'),
            now: $('#' + barId).attr('aria-valuemax')
        };
    };
    exports.setProcess = setProcess;
    exports.getProcess = getProcess;

    exports.getUploader = function (btnId, uiId, uploadedCallback, forAvatar) {
        var params = _getUploaderParams(btnId, forAvatar);
        $.extend(true, params, {
            init: {
                'FilesAdded': function (up, files) {
                    $('#processTable').show();
                    $('#success').hide();
                    plupload.each(files, function (file) {
                        var progress = new FileProgress(file, uiId);
                        progress.setStatus("等待...");
                        progress.bindUploadCancel(up);
                    });
                },
                'BeforeUpload': function (up, file) {
                    var progress = new FileProgress(file, uiId);
                    var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
                    if (up.runtime === 'html5' && chunk_size) {
                        progress.setChunkProgess(chunk_size);
                    }
                },
                'UploadProgress': function (up, file) {
                    var progress = new FileProgress(file, uiId);
                    var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
                    progress.setProgress(file.percent + "%", file.speed, chunk_size);
                },
                'UploadComplete': function () {
                    $('#success').show();
                },
                'FileUploaded': function (up, file, info) {
                    var progress = new FileProgress(file, uiId);
                    progress.setComplete(up, info);
                    var res = $.parseJSON(info);
                    var url;
                    if (res.url) {
                        url = res.url;
                    } else {
                        var domain = up.getOption('domain');
                        url = domain + encodeURI(res.key);
                    }
                    uploadedCallback(url);
                },
                'Error': function (up, err, errTip) {
                    $('#processTable').show();
                    var progress = new FileProgress(err.file, uiId);
                    progress.setError();
                    progress.setStatus(errTip);
                }
            }
        });
        var uploader = Qiniu.uploader(params);
        return uploader;
    };
    exports.getSimplerUploader = function (btnId, uploadedCallback, forAvatar) {
        var params = _getUploaderParams(btnId, forAvatar);
        $.extend(true, params, {
            init: {
                'FilesAdded': function (up, files) {
                    setProcess({
                        max: files.length,
                        now: 0
                    }, 'uploadprocess');
                    $('#uploadprocess').html('processing...');
                },
                'UploadComplete': function () {
                    setProcess({
                        max: 100,
                        now: 100
                    }, 'uploadprocess');
                    $('#uploadprocess').html('上传完毕');
                },
                'FileUploaded': function (up, file, info) {
                    var c = $('#uploadprocess').attr('aria-valuenow');
                    setProcess({
                        now: c + 1
                    });
                    var res = $.parseJSON(info);
                    var url;
                    if (res.url) {
                        url = res.url;
                    } else {
                        var domain = up.getOption('domain');
                        url = domain + encodeURI(res.key);
                    }
                    uploadedCallback(url);
                },
                'Error': function (up, err, errTip) {
                    $('#processTable').show();
                    var progress = new FileProgress(err.file, uiId);
                    progress.setError();
                    progress.setStatus(errTip);
                }
            }
        });
        var uploader = Qiniu.uploader(params);
        return uploader;
    };
    exports.getSingleUploader = function (btnId, uploadedCallback, silent, forAvatar) {
        var params = _getUploaderParams(btnId, forAvatar),
            originImg = null;
        $.extend(true, params, {
            init: {
                'FilesAdded': function (up, files) {
                    if (!silent) {
                        var img = $('#' + btnId).data('img');
                        originImg = $('#' + img).attr('src');
                        $('#' + img).attr("src", "lib/plugins/qiniu/loading.gif");
                    }
                },
                'FileUploaded': function (up, file, info) {
                    var res = $.parseJSON(info),
                        img = $('#' + btnId).data('img'),
                        url = '';
                    if (res.url) {
                        url = res.url;
                    } else {
                        var domain = up.getOption('domain');
                        url = domain + encodeURI(res.key);
                        $('#' + img).attr("src", url);
                        $('#' + img).parent('a.image-popup').attr('href', url);
                    }
                    if (uploadedCallback) uploadedCallback(url);
                },
                'Error': function (up, err, errTip) {
                    if (!silent) {
                        var img = $('#' + btnId).data('img');
                        $('#' + img).attr("src", originImg);
                    }
                    notify.error("上传错误", errTip);
                }
            }
        });
        var uploader = Qiniu.uploader(params);
        return uploader;
    };
    exports.getFileUploader = function (url, btn, callback) {
        var uploader = new plupload.Uploader({
            runtimes: 'html5,flash,silverlight,html4',
            browse_button: btn || 'importExcel',
            container: 'container',
            url: url,
            dragdrop: false,
            // chunk_size: "1mb",
            filters: {
                mime_types: [{
                    title: "Excel Files",
                    extensions: "xls,xlsx"
                }, ],
                max_file_size: "4mb",
                prevent_duplicates: false //不允许队列中存在重复文件
            },
            file_data_name: "excel_data",
            flash_swf_url: '/plupload/js/Moxie.swf',
            multi_selection: false,
            init: {
                'FilesAdded': function (up, files) {
                    up.start();
                },
                'UploadProgress': function (up, file) {
                    notify.warning("警告", "上传中，请耐心等待...");
                },
                'FileUploaded': function (up, file, info) {
                    if (callback) {
                        callback(JSON.parse(info.response));
                    } else {
                        notify.success("通知", "上传成功！");
                        setTimeout(function () {
                            location.reload();
                        }, 500);
                    }
                },
                'Error': function (up, err, errTip) {
                    notify.error("上传失败", errTip);
                    console.log(err);
                }
            }
        });
        uploader.init();
    };
});